﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EasyMvc.Models;
using EasyMvc.Utility;
using EasyMvc.DbContext;

namespace EasyMvc.Web.Common
{
    /// <summary>
    /// 用户标识上下文
    /// </summary>
    public class UserContext
    {
        public MyDbContext DbContext { get; set; }
        public User User { get; set; }
        public List<Role> Roles { get; set; }
        public Permission Permission { get; set; }

        public UserContext(string userName, MyDbContext dbContext)
        {
            this.DbContext = dbContext;

            if (string.IsNullOrEmpty(userName))
                return;

            var key = string.Format("UserContext_{0}", userName);
            if (Caching.Get(key) == null)
            {
                this.UpdateUserAndRoles(userName);
                this.UpdatePermission();
                Caching.Set(key, this);
            }
            else
            {
                var userContext = Caching.Get(key) as UserContext;
                this.User = userContext.User;
                this.Roles = userContext.Roles;
                this.Permission = userContext.Permission;
            }
        }

        /// <summary>
        /// 从数据库里取得用户和角色信息
        /// </summary>
        /// <param name="userName"></param>
        public void UpdateUserAndRoles(string userName)
        {
            this.User = this.DbContext.Users.SingleOrDefault(u => u.Username == userName);
            if (this.User != null)
            {
                var roleIdList = StringUtil.ConvertToIntList(User.RoleIds);
                this.Roles = this.DbContext.Roles.Where(r => roleIdList.Contains(r.Id)).ToList();
            }
        }

        /// <summary>
        /// 组合该用户每个角色的所有权限，取并集
        /// </summary>
        public void UpdatePermission()
        {
            this.Permission = new Permission();

            foreach (var role in this.Roles)
            {
                var permission = PermissionHelper.Parse(role.Permission);

                foreach (var vp in permission.ViewPermissions)
                {
                    if (!this.Permission.ViewPermissions.Contains(vp))
                        this.Permission.ViewPermissions.Add(vp);
                }
            }
        }
    }
}
